#!/bin/bash -eu
#
# Copyright 2020 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

source /opt/c2d/c2d-utils || exit 1

#######################################
# Checks if a host and port are opened
# Arguments:
#   Host name
#   Port number
#######################################
function await_for_host_and_port() {
  local -r HOST="$1"
  local -r PORT="$2"
  timeout --preserve-status 300 bash -c "until echo > /dev/tcp/${HOST}/${PORT}; do sleep 2; done"
  if [[ "$?" -ne 0 ]]; then
      exit 1
  fi
}

#######################################
# Check if user can connect to Elasticsearch API
# Arguments:
#  Elasticsearch protocol
#  Elasticsearch hostname
#  Elasticsearch user
#  Elasticsearch password
# Outputs:
#  String as '1' if user can connect or '0' if not
#######################################
function await_elasticsearch_credentials() {
  local -r protocol="$1"
  local -r hostname="$2"
  local -r auth_user="$3"
  local -r auth_user_pass="$4"
  local -r endpoint="${protocol}://${hostname}:9200"
  local response=""
  local retry=1
  local max_retries=10

  # Check if user can connect to Elasticsearch API
  # When an error occurs node status is returned
  while [[ "${retry}" -le "${max_retries}" && "${response}" != "null" ]]; do
    response="$(curl -s -k -u "${auth_user}:${auth_user_pass}" \
      "${endpoint}" | jq -r '.status')"

    retry="$((retry+1))"
    sleep 6
  done

  if [[ "${response}" != "null" ]]; then
    echo "Elasticsearch password not properly set."
    exit 1
  fi
}

#######################################
# Creates an user with provided credentials
# Arguments:
#  Elasticsearch protocol
#  Elasticsearch host
#  Elasticsearch user to authenticate
#  Elasticsearch password to authenticate
#  Elasticsearch user to be created
#  Elasticsearch password of the new user
#######################################
function create_user() {
  local -r protocol="$1"
  local -r hostname="$2"
  local -r auth_user="$3"
  local -r auth_user_pass="$4"
  local -r user_to_create="$5"
  local -r new_pass="$6"
  local -r endpoint="${protocol}://${hostname}:9200/_security/user/${user_to_create}"


  echo "Awaiting for Elasticsearch credentials to be set..."
  await_elasticsearch_credentials \
    "${protocol}" "${hostname}" \
    "${auth_user}" "${auth_user_pass}"

  echo "Credentials set. Creating user ${user_to_create}..."
  local response="$(curl -k -X POST \
                    -u "${auth_user}:${auth_user_pass}" \
                    -d "{\"password\":\"${new_pass}\", \"roles\": [\"kibana_admin\"] }" \
                    -H "Content-Type: application/json" \
                    "${endpoint}")"

  if [[ "${response}" != '{"created":true}' ]]; then
    echo "User creation failed: ${response}"
    exit 1
  fi
}
